﻿using System;
using BITS.PreCompiler.CSharp.Syntax;
using BITS.PreCompiler.CSharp.Syntax.Extensions;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace BITS.PreCompiler.CSharp.Tests.Syntax
{
    [TestClass]
    public class TestProperty : TestBase
    {
        [TestMethod]
        public void Create_Property()
        {
            var proeprty = new Property(@return: "int", identifier: "Create_Property")
                .WithAutoAccessors();

            var expectet = Comparer.Create_Property();
            var actual   = proeprty.ToString();

            Assert.AreEqual(expectet, actual);
            Console.WriteLine(actual);
        }

        [TestMethod]
        public void Create_Property_With_Generic_Return_Type()
        {
            var proeprty = new Property(@return: "IList<int>", identifier: "Create_Property_With_Generic_Return_Type")
                .WithAutoAccessors();

            var expectet = Comparer.Create_Property_With_Generic_Return_Type();
            var actual   = proeprty.ToString();

            Assert.AreEqual(expectet, actual);
            Console.WriteLine(actual);

            proeprty = new Property(identifier: "Create_Property_With_Generic_Return_Type")
                .WithAutoAccessors()
                .WithReturnType("IList<int>");

            expectet = Comparer.Create_Property_With_Generic_Return_Type();
            actual   = proeprty.ToString();

            Assert.AreEqual(expectet, actual);
            Console.WriteLine(actual);

            proeprty = new Property(identifier: "Create_Property_With_Generic_Return_Type")
                .WithAutoAccessors()
                .WithReturnType(new Interface("IList")
                        .WithTypeParameter("int").TypeSyntax);

            expectet = Comparer.Create_Property_With_Generic_Return_Type();
            actual   = proeprty.ToString();

            Assert.AreEqual(expectet, actual);
            Console.WriteLine(actual);
        }

        [TestMethod]
        public void Create_Property_With_Strings()
        {
            var proeprty = new Property(@return: "int", identifier: "A")
            {
                @"get;",
                @"set;",
            };

            var expectet = Comparer.Create_Property_With_Strings();
            var actual = proeprty.ToString();

            Assert.AreEqual(expectet, actual);
            Console.WriteLine(actual);
        }

        [TestMethod]
        public void Create_Property_With_String_Members_And_Strong_Typed_Members()
        {
            var proeprty = new Property(@return: "NewClass", identifier: "Create_Property_With_String_Members_And_Strong_Typed_Members")
            {
                @"get { return new NewClass(); }",
                @"set { return null; }",
            };

            var expectet = Comparer.Create_Property_With_String_Members_And_Strong_Typed_Members();
            var actual   = proeprty.ToString();

            Assert.AreEqual(expectet, actual);
            Console.WriteLine(actual);
        }

        [TestMethod]
        public void Create_Property_With_String_Members_And_Strong_Typed_Getter()
        {
            var proeprty = new Property(@return: "NewClass", identifier: "Create_Property_With_String_Members_And_Strong_Typed_Getter")
            {
                new Property.Get
                {
                    @"return new NewClass();",
                },
                @"set { return null; }",
            };

            var expectet = Comparer.Create_Property_With_String_Members_And_Strong_Typed_Getter();
            var actual   = proeprty.ToString();

            Assert.AreEqual(expectet, actual);
            Console.WriteLine(actual);
        }

        [TestMethod]
        public void Create_Property_Strong_Typed_Accessors()
        {
            var proeprty = new Property(@return: "NewClass", identifier: "Create_Property_Strong_Typed_Accessors")
            {
                new Property.Get
                {
                    @"return new NewClass();",
                },
                new Property.Set
                {
                    @"this.Member = value;",
                },
            };

            var expectet = Comparer.Create_Property_Strong_Typed_Accessors();
            var actual   = proeprty.ToString();

            Assert.AreEqual(expectet, actual);
            Console.WriteLine(actual);
        }




        public static class Comparer
        {
            public static String Create_Property()
            {
                return
@"private int Create_Property { get; set; }";
            }

            public static String Create_Property_With_Generic_Return_Type()
            {
                return
@"private IList<int> Create_Property_With_Generic_Return_Type { get; set; }";
            }

            public static String Create_Property_With_Strings()
            {
                return
@"private int A { get; set; }";
            }

            public static String Create_Property_With_String_Members_And_Strong_Typed_Members()
            {
                return
@"private NewClass Create_Property_With_String_Members_And_Strong_Typed_Members
{
    get
    {
        return new NewClass();
    }

    set
    {
        return null;
    }
}";
            }

            public static String Create_Property_With_String_Members_And_Strong_Typed_Getter()
            {
                return
@"private NewClass Create_Property_With_String_Members_And_Strong_Typed_Getter
{
    get
    {
        return new NewClass();
    }

    set
    {
        return null;
    }
}";
            }

            public static String Create_Property_Strong_Typed_Accessors()
            {
                return
@"private NewClass Create_Property_Strong_Typed_Accessors
{
    get
    {
        return new NewClass();
    }

    set
    {
        this.Member = value;
    }
}";
            }
        }
    }
}
